﻿using System;
using System.Collections.Generic;
using System.Text;
using SharpDX.DirectWrite;
using System.Drawing;
using OpenGameEngine.GameObjects;
using OpenGameEngine.Base;
using OpenGameEngine.Input;
using SharpDX;
using System.Windows.Forms;
using OpenGameEngine;

namespace OpenGameEngine.Hud
{
    public class HudLabel
        : GameObject
    {
        #region IDisposable
        private Boolean _disposed = false;

        ~HudLabel()
        {
            if (!_disposed)
            {
                Dispose(false);
                _disposed = true;
            }
        }

        public void Dispose()
        {
            if (!_disposed)
            {
                Dispose(true);
                _disposed = true;
            }
            GC.SuppressFinalize(this);
        }

        public void Dispose(Boolean disposeManagedResources)
        {
            if (disposeManagedResources)
            {

            }
        }
        #endregion

        private bool _mouseEntered = false;
        private bool _mouseDown = false;

        public Font Font { get; set; }
        public Color TextColor { get; set; }
        public Color BackColor { get; set; }

        public RectangleF ActualBounds { get; private set; }
        public SizeF ActualSize { get { return new SizeF(ActualBounds.Width, ActualBounds.Height); } }
        public Vector2 ActualPosition { get { return new Vector2(ActualBounds.X, ActualBounds.Y); } }
        public Boolean UseCenterPositioning { get; set; }
        public SizeF ProposedSize { get; set; }
        public Boolean AutoSize;

        private SizeF _labelSize;
        private GameConfiguration gc;
        private TextLayout layout;

        private MouseStateInfo _prevMouse;
        private MouseStateInfo _mouse;
        private Vector2 _v;
        private RectangleF _d;
        private bool blnCurrMs;
        private bool blnPrevMs;

        private SolidColorBrush backBrush { get { return new SolidColorBrush(BackColor); } }
        private SolidColorBrush textBrush { get { return new SolidColorBrush(TextColor); } }

        public String Text { get; set; }

        public HudLabel()
            : base()
        {
            Text = "HudLabel.{" + UniqueID.ToString() + "}";
            BackColor = Color.Transparent;
            TextColor = Color.White;
            Font = new Font("Comic Sans MS", 12f);
            Visible = true;
            Enabled = true;
            AutoSize = true;
            AcceptsMouseInput = true;
            AcceptsKeyboardInput = true;
        }

        public HudLabel(String text)
            : this()
        {
            this.Text = text;
        }

        public HudLabel(float x, float y)
            : this()
        {
            this.Position = new Vector2(x, y);
        }

        public HudLabel(String text, float x, float y)
            : this()
        {
            this.Text = text;
            this.Position = new Vector2(x, y);
        }

        public override void Update(Base.GameCoreEventArgs e)
        {
            base.Update(e);
            if (Text != String.Empty && Text.Length > 0)
            {
                layout = Font.MakeLayout(Text, Font);

                if (AutoSize)
                {
                    _labelSize = new SizeF(layout.Metrics.Width, layout.Metrics.Height);
                }
                else
                {
                    _labelSize = ProposedSize;
                }

                if (UseCenterPositioning)
                {
                    gc = e.Core.Config;

                    this.ActualBounds = new RectangleF(
                        (gc.Width / 2) - (_labelSize.Width / 2) + Position.X,
                        (gc.Height / 2) - (_labelSize.Height / 2) + Position.Y,
                        _labelSize.Width, _labelSize.Height);
                }
                else
                {
                    //SharpDX.Vector2 vc2 = new SharpDX.Vector2(
                    this.ActualBounds = new RectangleF(Position.X, Position.Y, _labelSize.Width, _labelSize.Height);
                }
            }
            else
                this.ActualBounds = new RectangleF(this.Position.X, this.Position.Y, 0, 0);

            CheckForInput(e);

        }

        private void CheckForInput(GameCoreEventArgs e)
        {
            if (AcceptsMouseInput)
            {
                _prevMouse = e.Core.PreviousMouseStateInfo;
                _mouse = e.Core.CurrentMouseStateInfo;
                _v = _mouse.MouseLocation;
                _d = this.ActualBounds;

                // check if mouse is inside

                if (_v.X > _d.X && _v.Y > _d.Y && _v.X < (_d.X + _d.Width) && _v.Y < (_d.Y + _d.Height))
                {
                    if (!_mouseEntered)
                    {
                        MouseEnter(e);
                        _mouseEntered = true;
                    }

                    foreach (MouseButtons b in Globals.MouseButtons)
                    {
                        blnCurrMs = _mouse[b];
                        blnPrevMs = _prevMouse[b];

                        if (blnCurrMs)
                        {
                            MouseDown(e, b);
                        }
                        else if (blnPrevMs && !blnCurrMs)
                        {
                            MouseUp(e, b);
                            MouseClick(e, b);
                        }
                    }
                }
                else
                {
                    if (_mouseEntered)
                    {
                        MouseLeave(e);
                        _mouseEntered = false;
                    }
                }
            }
        }

        //public override void Input(GameCoreEventArgs e)
        //{
        //    base.Input(e);
        //}

        public override void Draw(Base.DrawEventArgs e)
        {
            base.Draw(e);

            if (Text != String.Empty && Text.Length > 0)
            {
                using (RectangleF rect = new RectangleF(Position.X, Position.Y, layout.Metrics.Width, layout.Metrics.Height))
                {
                    Globals.RenderTarget.FillRectangle(rect, backBrush);
                    e.DrawString(Text, Font, textBrush, rect);
                }
                

                
                // e.Target.DrawRectangle(ActualBounds, textBrush);
            }
        }
    }
}
